/*
	gamerules.h

	Copyright (C) 2004 WildTangent, Inc. 
	All Rights Reserved

	Travis Baldree
	9/15/2004

*/
#ifndef _GAMERULES_H
#define _GAMERULES_H

#pragma warning(disable: 4786) 

#include <math.h>
#include "../UTILITIES/constants.h"
#include "../UTILITIES/loadlocalizedstring.h"
#include "../GAME/game.h"

const std::string KSaveExtension = "FFD";

enum ERank
{
	KRankNormal,
	KRankElite,
	KRankLegendary,
	KRanks
};

static std::string GetRankName( int Rank )
{
	switch ( Rank )
	{
	case 1: return LoadLocalizedString(215);
	case 2: return LoadLocalizedString(216);
	default:
		return std::string();
	}
};

const uint32 KRankLevelOffset[KRanks] =
{
	0,
	12,
	30
};

const float32 KRankPowerMultiplier[KRanks] =
{
	1,
	2,
	4
};

const float32 KRankToHitMultiplier[KRanks] =
{
	1,
	1.25f,
	2
};

const float32 KRankExperienceMultiplier[KRanks] =
{
	1,
	1.1f,
	1.2f
};

const float32 KRankItemRarityMultiplier[KRanks] =
{
	1,
	5,
	10
};

const float32 KRankMonsterRarityMultiplier[KRanks] =
{
	1,
	10,
	20
};

const float32 KRankRequirementMultiplier[KRanks] =
{
	1,
	1.5,
	2
};

const float32 KRankPriceMultiplier[KRanks] =
{
	1,
	3,
	6
};

enum EHighlightColor
{
	KHighlightLightPurple,
	KHighlightRed,
	KHighlightGreen,
	KHighlightDarkRed,
	KHighlightYellow,
	KHighlightDarkPurple,
	KHighlightBlue,
	KHighlightGray,
	KHighlightTeal,
	KHighlightBlack,
	KHighlightColors
};

enum EGrade
{
	KGradeNormal,
	KGradeSuperior,
	KGradeExceptional,
	KGradeFlawless,
	KGrades
};

enum EJournalStatistic
{
	KJournalStatTimePlayed,
	KJournalStatStepsTaken,
	KJournalStatGoldGathered,
	KJournalStatQuestsCompleted,
	KJournalStatLevelsExplored,
	KJournalStatDeaths,
	KJournalStatMonstersKilled,
	KJournalStatFamousMonstersKilled,
	KJournalStatSpellsCast,
	KJournalStatChestsOpened,
	KJournalStatLargeChestsOpened,
	KJournalStatTrapsSprung,
	KJournalStatBarrelsBroken,
	KJournalStatPotionsUsed,
	KJournalStatPortalsUsed,
	KJournalStatFishCaught,
	KJournalStatTimesGambled,
	KJournalStatistics
};

static std::string GetJournalStatName( int JournalStatistic )
{
	switch ( JournalStatistic )
	{
	case 0: return LoadLocalizedString(217);
	case 1: return LoadLocalizedString(218);
	case 2: return LoadLocalizedString(219);
	case 3: return LoadLocalizedString(220);
	case 4: return LoadLocalizedString(221);
	case 5: return LoadLocalizedString(222);
	case 6: return LoadLocalizedString(223);
	case 7: return LoadLocalizedString(224);
	case 8: return LoadLocalizedString(225);
	case 9: return LoadLocalizedString(226);
	case 10: return "LargeChest";
	case 11: return LoadLocalizedString(227);
	case 12: return LoadLocalizedString(228);
	case 13: return LoadLocalizedString(229);
	case 14: return LoadLocalizedString(230);
	case 15: return LoadLocalizedString(231);
	case 16: return LoadLocalizedString(232);
	default:
		return std::string();
	}
};

static std::string GetGradeName( int Grade ) 
{
	switch ( Grade )
	{
	case 1: return LoadLocalizedString(233);
	case 2: return LoadLocalizedString(234);
	case 3: return LoadLocalizedString(235);
	default:
		return std::string();
	}
};

const float32 KGradeBonus[KGrades] =
{
	0,
	20,
	40,
	60
};

const uint32 KFameLevels( 21 );
const uint32 KFameGate[KFameLevels] =
{
	0,
	500,
	1000,
	2000,
	4000,
	8000,
	12000,
	20000,
	36000,
	68000,
	100000,
	164000,
	292000,
	548000,
	1188000,
	3236000,
	7332000,
	15524000,
	23716000,
	40100000,
	40100000
};

static std::string GetFameName( int FameLevel )
{
	switch ( FameLevel )
	{
	case 0: return LoadLocalizedString(236);
	case 1: return LoadLocalizedString(236);
	case 2: return LoadLocalizedString(237);
	case 3: return LoadLocalizedString(238);
	case 4: return LoadLocalizedString(239);
	case 5: return LoadLocalizedString(240);
	case 6: return LoadLocalizedString(241);
	case 7: return LoadLocalizedString(242);
	case 8: return LoadLocalizedString(243);
	case 9: return LoadLocalizedString(244);
	case 10: return LoadLocalizedString(245);
	case 11: return LoadLocalizedString(246);
	case 12: return LoadLocalizedString(247);
	case 13: return LoadLocalizedString(248);
	case 14: return LoadLocalizedString(249);
	case 15: return LoadLocalizedString(250);
	case 16: return LoadLocalizedString(251);
	case 17: return LoadLocalizedString(252);
	case 18: return LoadLocalizedString(253);
	case 19: return LoadLocalizedString(254);
	case 20: return LoadLocalizedString(255);
	default:
		return std::string();
	}
};

enum EGender
{
	KMale,
	KFemale,
	KGenders
};

enum EDifficulty
{
	KDifficultyPage,
	KDifficultyAdventurer,
	KDifficultyHero,
	KDifficultyLegend,
	KDifficulties
};

const float32 KDifficultyLevelBase[KDifficulties] =
{
	-5,
	0,
	1,
	3
};

const float32 KDifficultyMultiplier[KDifficulties] =
{
	.75f,
	1,
	1.5f,
	2
};

const float32 KDifficultyAppearanceMultiplier[KDifficulties] =
{
	.75f,
	1,
	1.5f,
	3
};

const float32 KDifficultyItemMultiplier[KDifficulties] =
{
	.75f,
	1,
	1.2f,
	1.4f
};

static std::string GetDifficultyName( EDifficulty Difficulty )
{
	switch ( Difficulty )
	{
	case KDifficultyPage: return LoadLocalizedString( 256 );
	case KDifficultyAdventurer: return LoadLocalizedString( 257 );
	case KDifficultyHero: return LoadLocalizedString( 258 );
	case KDifficultyLegend: return LoadLocalizedString( 259 );
	default:
		return std::string();
	}
};

enum EQuestType 
{
	KQuestKillMonster,
	KQuestKillMonsters,
	KQuestMonsterItem,
	KQuestFindItem,
	KQuestKillArmy,
	KQuestArmyItem,
//	KQuestFindItems,
//	KQuestFindLost,
	KQuestMasterQuest,
	KQuestTypes
//	KQuestClearLevel,
};

enum EMiniMapDolly
{
	KMapNormal,
	KMapHigh,
	KMapHigher,
	KMapHighest,
	KMiniMapHeights
};

static std::string GetQuestName( EQuestType QuestType )
{
	switch ( QuestType )
	{
	case KQuestKillMonster:
		return "KILLMONSTER";
	case KQuestKillMonsters:
		return "KILLMONSTERS";
	case KQuestMonsterItem:
		return "MONSTERITEM";
	case KQuestFindItem:
		return "FINDITEM";
	case KQuestKillArmy:
		return "KILLARMY";
	case KQuestArmyItem:
		return "ARMYITEM";
	case KQuestMasterQuest:
		return "MASTERQUEST";
	default:
		return std::string();
	}
};

enum ETrapType
{
	KTrapNone,
	KTrapExplosion,
	KTrapPoison,
	KTrapMonster,
	KTrapSword,
	KTrapTypes
};

enum EAlignment
{
	KNeutral,
	KGood,
	KEvil,
	KAllAlignments,
	KAlignments
};

static std::string GetAlignmentName( uint32 Alignment ) 
{
	switch ( Alignment )
	{
	case 0:
		return "NEUTRAL";
	case 1:
		return "GOOD";
	case 2:
		return "EVIL";
	case 3:
		return "ALL";
	default:
		return std::string();
	}
};

enum ESFXType
{
	KSFXStationaryTarget,
	KSFXStationaryOwner,
	KSFXStationary,
	KSFXStationaryPortal,
	KSFXBeam,
	KSFXFollowOwner,
	KSFXFollowTarget,
	KSFXProjectileLocation,
	KSFXProjectileCharacter,
	KSFXProjectileLocationErratic,
	KSFXProjectileCharacterErratic,
	KSFXTypes
};

const std::string KSFXTypeName[KSFXTypes] =
{
	"STATIONARYTARGET",
	"STATIONARYOWNER",
	"STATIONARY",
	"STATIONARYPORTAL",
	"BEAM",
	"FOLLOWOWNER",
	"FOLLOWTARGET",
	"PROJECTILELOCATION",
	"PROJECTILECHARACTER",
	"PROJECTILELOCATIONERRATIC",
	"PROJECTILECHARACTERERRATIC",
};

enum ETactic
{
	KTacticsFighter,
	KTacticsMage,
	KTacticsFighterMage,
	KTacticsDarter,
	KTactics
};

const std::string KTacticNames[KTactics] =
{
	"FIGHTER",
	"MAGE",
	"FIGHTERMAGE",
	"DARTER"
};


enum EMagicSphere
{
	KMagicAttack,
	KMagicDefense,
	KMagicCharm,
	KMagicSpheres
};


const std::string KMagicSphereName[KMagicSpheres] = 
{
	"ATTACK",
	"DEFENSE",
	"CHARM"
};

static std::string GetMagicSphereShortName( uint32 MagicSphere ) 
{
	switch ( MagicSphere )
	{
	case 0: return LoadLocalizedString(260);
	case 1:	return LoadLocalizedString(261);
	case 2:	return LoadLocalizedString(262);
	default:
		return std::string();
	}
};

enum EAttackSpeed
{
	KAttackSlowest,
	KAttackSlow,
	KAttackNormal,
	KAttackFast,
	KAttackFastest,
	KAttackSpeeds
};

enum EDamageType
{
	KDamagePiercing,
	KDamageSlashing,
	KDamageCrushing,
	KDamageMagical,
	KDamageFire,
	KDamageIce,
	KDamageElectric,
	KDamageUndead,
	KDamageTypes
};

static std::string GetDamageTypeDescription( uint32 DamageType )
{
	switch ( DamageType )
	{
	case 0:	return LoadLocalizedString(263);
	case 1:	return LoadLocalizedString(264);
	case 2:	return LoadLocalizedString(265);
	case 3:	return LoadLocalizedString(266);
	case 4:	return LoadLocalizedString(267);
	case 5:	return LoadLocalizedString(268);
	case 6:	return LoadLocalizedString(269);
	case 7:	return LoadLocalizedString(270);
	default:
		return std::string();
	}
};

static std::string GetDamageResistanceDescription( uint32 DamageType )
{
	switch ( DamageType )
	{
	case 0:	return LoadLocalizedString(271);
	case 1:	return LoadLocalizedString(272);
	case 2:	return LoadLocalizedString(273);
	case 3:	return LoadLocalizedString(274);
	case 4:	return LoadLocalizedString(275);
	case 5:	return LoadLocalizedString(276);
	case 6:	return LoadLocalizedString(277);
	case 7:	return LoadLocalizedString(278);
	default:
		return std::string();
	}
};

static std::string GetDamageWeaknessDescription( uint32 DamageType )
{
	switch ( DamageType )
	{
	case 0:	return LoadLocalizedString(279);
	case 1:	return LoadLocalizedString(280);
	case 2:	return LoadLocalizedString(281);
	case 3:	return LoadLocalizedString(282);
	case 4:	return LoadLocalizedString(283);
	case 5:	return LoadLocalizedString(284);
	case 6:	return LoadLocalizedString(285);
	case 7:	return LoadLocalizedString(286);
	default:
		return std::string();
	}
};

const std::string KDamageNames[KDamageTypes] =
{
	"PIERCING",
	"SLASHING",
	"CRUSHING",
	"MAGIC",
	"FIRE",
	"ICE",
	"ELECTRIC",
	"UNDEAD"
};

static std::string GetDamageWeaponPrefix( uint32 DamageType )
{
	switch ( DamageType )
	{
	case 4: return LoadLocalizedString(287);
	case 5: return LoadLocalizedString(288);
	case 6: return LoadLocalizedString(289);
	case 7: return LoadLocalizedString(290);
	default:
		return std::string();
	}
};

const std::string KDamageParticles[KDamageTypes] =
{
	"",
	"",
	"",
	"",
	"FIRE",
	"ICE",
	"ELECTRIC",
	"TINYFASTGLEAM"
};

const std::string KDamageParticlesSecondary[KDamageTypes] =
{
	"",
	"",
	"",
	"",
	"BIGFIRESPARK",
	"SMALLSNOWFLAKE",
	"",
	""
};

enum EStatistic
{
	KStatStrength,
	KStatDexterity,
	KStatVitality,
	KStatMagic,
	KStatLevel,
	KStatRenown,
	KStatLineage,
	KStatSkillSword,
	KStatSkillClub,
	KStatSkillHammer,
	KStatSkillAxe,
	KStatSkillSpear,
	KStatSkillStaff,
	KStatSkillPolearm,
	KStatSkillBow,
	KStatSkillCriticalStrike,
	KStatSkillSpellcasting,
	KStatSkillDualWield,
	KStatSkillShield,
	KStatSkillAttackMagic,
	KStatSkillDefenseMagic,
	KStatSkillCharmMagic,
	KStatistics
};

const std::string KStatisticName[KStatistics] =
{
	"STRENGTH",
	"DEXTERITY",
	"VITALITY",
	"MAGIC",
	"LEVEL",
	"RENOWN",
	"LINEAGE",
	"SKILLSWORD",
	"SKILLCLUB",
	"SKILLHAMMER",
	"SKILLAXE",
	"SKILLSPEAR",
	"SKILLSTAFF",
	"SKILLPOLEARM",
	"SKILLBOW",
	"SKILLCRITICALSTRIKE",
	"SKILLSPELLCASTING",
	"SKILLDUALWIELD",
	"SKILLSHIELD",
	"SKILLATTACKMAGIC",
	"SKILLDEFENSEMAGIC",
	"SKILLCHARMMAGIC"
};

static std::string GetStatisticDescription( uint32 StatisticsName )
{
	switch ( StatisticsName )
	{
	case 0: return LoadLocalizedString(291);
	case 1: return LoadLocalizedString(292);
	case 2: return LoadLocalizedString(293);
	case 3: return LoadLocalizedString(294);
	case 4: return LoadLocalizedString(295);
	case 5: return LoadLocalizedString(296);
	case 6: return LoadLocalizedString(297);
	case 7: return LoadLocalizedString(298);
	case 8: return LoadLocalizedString(299);
	case 9: return LoadLocalizedString(300);
	case 10: return LoadLocalizedString(301);
	case 11: return LoadLocalizedString(302);
	case 12: return LoadLocalizedString(303);
	case 13: return LoadLocalizedString(304);
	case 14: return LoadLocalizedString(305);
	case 15: return LoadLocalizedString(306);
	case 16: return LoadLocalizedString(307);
	case 17: return LoadLocalizedString(308);
	case 18: return LoadLocalizedString(309);
	case 19: return LoadLocalizedString(310);
	case 20: return LoadLocalizedString(311);
	case 21: return LoadLocalizedString(312);
	default:
		return std::string();
	}
};

const float32 KAttackSpeedValue[KAttackSpeeds] =
{
	.6f,
	.8f,
	1.0f,
	1.1f,
	1.2f
};

static std::string GetAttackSpeedName( int AttackSpeed )
{
	switch ( AttackSpeed )
	{
	case 0: return LoadLocalizedString(313);
	case 1: return LoadLocalizedString(314);
	case 2: return LoadLocalizedString(315);
	case 3: return LoadLocalizedString(316);
	case 4: return LoadLocalizedString(317);
	default:
		return std::string();
	}
};


enum ESkill
{
	KSkillSword,
	KSkillClub,
	KSkillHammer,
	KSkillAxe,
	KSkillSpear,
	KSkillStaff,
	KSkillPolearm,
	KSkillBow,
	KSkillCriticalStrike,
	KSkillSpellcasting,
	KSkillDualWield,
	KSkillShield,
	KSkillAttackMagic,
	KSkillDefenseMagic,
	KSkillCharmMagic,
	KSkills
};

const std::string KSkillNames[KSkills] =
{
	"SKILLSWORD",
	"SKILLCLUB",
	"SKILLHAMMER",
	"SKILLAXE",
	"SKILLSPEAR",
	"SKILLSTAFF",
	"SKILLPOLEARM",
	"SKILLBOW",
	"SKILLCRITICALSTRIKE",
	"SKILLSPELLCASTING",
	"SKILLDUALWIELD",
	"SKILLSHIELD",
	"SKILLATTACKMAGIC",
	"SKILLDEFENSEMAGIC",
	"SKILLCHARMMAGIC"
};

static std::string GetSkillDescription( int Skill )
{
	switch ( Skill )
	{
	case 0: return LoadLocalizedString(298);
	case 1: return LoadLocalizedString(299);
	case 2: return LoadLocalizedString(300);
	case 3: return LoadLocalizedString(301);
	case 4: return LoadLocalizedString(302);
	case 5: return LoadLocalizedString(303);
	case 6: return LoadLocalizedString(304);
	case 7: return LoadLocalizedString(305);
	case 8: return LoadLocalizedString(306);
	case 9: return LoadLocalizedString(307);
	case 10: return LoadLocalizedString(308);
	case 11: return LoadLocalizedString(309);
	case 12: return LoadLocalizedString(310);
	case 13: return LoadLocalizedString(311);
	case 14: return LoadLocalizedString(312);
	default:
		return std::string();
	}
};

static std::string GetSkillExplanation( int Skill )
{
	switch ( Skill )
	{
	case 0: return LoadLocalizedString(318);
	case 1: return LoadLocalizedString(319);
	case 2: return LoadLocalizedString(320);
	case 3: return LoadLocalizedString(321);
	case 4: return LoadLocalizedString(322);
	case 5: return LoadLocalizedString(323);
	case 6: return LoadLocalizedString(324);
	case 7: return LoadLocalizedString(325);
	case 8: return LoadLocalizedString(326);
	case 9: return LoadLocalizedString(327);
	case 10: return LoadLocalizedString(328);
	case 11: return LoadLocalizedString(329);
	case 12: return LoadLocalizedString(330);
	case 13: return LoadLocalizedString(331);
	case 14: return LoadLocalizedString(332);
	default:
		return std::string();
	}
};

enum EItemCategory
{
	KCategoryBlank,
	KCategoryGold,
	KCategoryItem,
	KCategoryContainer,
	KCategoryWeapon,
	KCategoryArmor,
	KCategoryJewelry,
	KCategoryEvent,
	KItemCategories
};

enum EItemType
{
	KItemNone,
	KItemStairsUp,
	KItemStairsDown,
	KItemTownPortal,
	KItemDungeonPortal,
	KItemFishingHole,
	KItemGold,
	KItemGeneric,
	KItemPotion,
	KItemWeaponRack,
	KItemContainer,
	KItemChestSmall,
	KItemChestMedium,
	KItemChestLarge,
	KItemSword,
	KItemClub,
	KItemHelmet,
	KItemShield,
	KItemSpear,
	KItemBow,
	KItemBelt,
	KItemNecklace,
	KItemRing,
	KItemGloves,
	KItemBoots,
	KItemShirt,
	KItemPolearm,
	KItemScroll,
	KItemBook,
	KItemSpell,
	KItemAxe,
	KItemHammer,
	KItemStaff,
	KItemCrossbow,
	KItemGem,
	KItemPetFood,
	KItemFishingPole,
	KItemMagicAnvil,
	KItemShrine,
	KItemFountain,
	KItemThrone,
	KItemStatue,
	KItemHealFountain,
	KItemManaFountain,
	KItemStaminaFountain,
	KItemWellnessFountain,
	KItemTypes
};

enum EMerchant
{
	KMerchantTraveling,
	KMerchantGoods,
	KMerchantWeapons,
	KMerchantArmor,
	KMerchantWeaponsArmor,
	KMerchantMagic,
	KMerchantPotions,
	KMerchantGambler,
	KMerchantStash,
	KMerchantBreakGems,
	KMerchantBreakWeapons,
	KMerchantMinstrel,
	KMerchantHealer,
	KMerchantFish,
	KMerchantEnchanter,
	KMerchantTypes
};

const std::string KMerchantName[KMerchantTypes] = 
{
	"TRAVELING",
	"GOODS",
	"WEAPONS",
	"ARMOR",
	"WEAPONSARMOR",
	"MAGIC",
	"POTIONS",
	"GAMBLER",
	"STASH",
	"BREAKGEMS",
	"BREAKWEAPONS",
	"MINSTREL",
	"HEALER",
	"FISH",
	"ENCHANTER"
};

const std::string KItemTypeName[KItemTypes] = 
{
	"NONE",
	"STAIRSUP",
	"STAIRSDOWN",
	"TOWNPORTAL",
	"DUNGEONPORTAL",
	"FISHINGHOLE",
	"GOLD",
	"GENERIC",
	"POTION",
	"WEAPONRACK",
	"CONTAINER",
	"CHESTSMALL",
	"CHESTMEDIUM",
	"CHESTLARGE",
	"SWORD",
	"CLUB",
	"HELMET",
	"SHIELD",
	"SPEAR",
	"BOW",
	"BELT",
	"NECKLACE",
	"RING",
	"GLOVES",
	"BOOTS",
	"SHIRT",
	"POLEARM",
	"SCROLL",
	"BOOK",
	"SPELL",
	"AXE",
	"HAMMER",
	"STAFF",
	"CROSSBOW",
	"GEM",
	"PETFOOD",
	"FISHINGPOLE",
	"MAGICANVIL",
	"SHRINE",
	"FOUNTAIN",
	"THRONE",
	"STATUE",
	"HEALFOUNTAIN",
	"MANAFOUNTAIN",
	"STAMINAFOUNTAIN",
	"WELLNESSFOUNTAIN"
};

const EDamageType KItemDamageType[KItemTypes] =
{
	KDamageSlashing,
	KDamageSlashing,
	KDamageSlashing,
	KDamageSlashing,
	KDamageSlashing,
	KDamageSlashing,
	KDamageSlashing,
	KDamageSlashing,
	KDamageSlashing,
	KDamageSlashing,
	KDamageSlashing,
	KDamageSlashing,
	KDamageSlashing,
	KDamageSlashing,
	KDamageSlashing,
	KDamageCrushing,
	KDamageSlashing,
	KDamageSlashing,
	KDamagePiercing,
	KDamagePiercing,
	KDamageSlashing,
	KDamageSlashing,
	KDamageSlashing,
	KDamageSlashing,
	KDamageSlashing,
	KDamageSlashing,
	KDamagePiercing,
	KDamageSlashing,
	KDamageSlashing,
	KDamageSlashing,
	KDamageSlashing,
	KDamageCrushing,
	KDamageCrushing,
	KDamagePiercing,
	KDamageSlashing,
	KDamageSlashing,
	KDamageSlashing,
	KDamageSlashing,
	KDamageSlashing,
	KDamageSlashing,
	KDamageSlashing,
	KDamageSlashing,
	KDamageSlashing,
	KDamageSlashing,
	KDamageSlashing,
	KDamageSlashing
};

const bool KItemTwoHanded[KItemTypes] = 
{
	kFalse,
	kFalse,
	kFalse,
	kFalse,
	kFalse,
	kFalse,
	kFalse,
	kFalse,
	kFalse,
	kFalse,
	kFalse,
	kFalse,
	kFalse,
	kFalse,
	kFalse,
	kFalse,
	kFalse,
	kFalse,
	kFalse,
	kTrue,
	kFalse,
	kFalse,
	kFalse,
	kFalse,
	kFalse,
	kFalse,
	kTrue,
	kFalse,
	kFalse,
	kFalse,
	kFalse,
	kFalse,
	kTrue,
	kTrue,
	kFalse,
	kFalse,
	kFalse,
	kFalse,
	kFalse,
	kFalse,
	kFalse,
	kFalse,
	kFalse,
	kFalse,
	kFalse,
	kFalse
};

const bool KItemRightHanded[KItemTypes] = 
{
	kTrue,
	kTrue,
	kTrue,
	kTrue,
	kTrue,
	kTrue,
	kTrue,
	kTrue,
	kTrue,
	kTrue,
	kTrue,
	kTrue,
	kTrue,
	kTrue,
	kTrue,
	kTrue,
	kTrue,
	kTrue,
	kTrue,
	kFalse,
	kTrue,
	kTrue,
	kTrue,
	kTrue,
	kTrue,
	kTrue,
	kTrue,
	kFalse,
	kFalse,
	kFalse,
	kTrue,
	kTrue,
	kTrue,
	kTrue,
	kFalse,
	kFalse,
	kFalse,
	kFalse,
	kFalse,
	kFalse,
	kFalse,
	kFalse,
	kFalse,
	kFalse,
	kFalse,
	kFalse
};

static std::string GetItemTypeDescription( int ItemType ) 
{
	switch ( ItemType )
	{

	case 14: return LoadLocalizedString(333);
	case 15: return LoadLocalizedString(334);
	case 16: return LoadLocalizedString(335);
	case 17: return LoadLocalizedString(336);
	case 18: return LoadLocalizedString(337);
	case 19: return LoadLocalizedString(338);
	case 20: return LoadLocalizedString(339);
	case 21: return LoadLocalizedString(340);
	case 22: return LoadLocalizedString(340);
	case 23: return LoadLocalizedString(341);
	case 24: return LoadLocalizedString(342);
	case 25: return LoadLocalizedString(343);
	case 26: return LoadLocalizedString(344);
	case 30: return LoadLocalizedString(345);
	case 31: return LoadLocalizedString(346);
	case 32: return LoadLocalizedString(347);
	case 33: return LoadLocalizedString(348);
	default:
		return std::string();
	}
};

const EItemCategory	KItemCategory[KItemTypes] =
{
	KCategoryBlank,
	KCategoryBlank,
	KCategoryBlank,
	KCategoryBlank,
	KCategoryBlank,
	KCategoryBlank,
	KCategoryGold,
	KCategoryItem,
	KCategoryItem,
	KCategoryContainer,
	KCategoryContainer,
	KCategoryContainer,
	KCategoryContainer,
	KCategoryContainer,
	KCategoryWeapon,
	KCategoryWeapon,
	KCategoryArmor,
	KCategoryArmor,
	KCategoryWeapon,
	KCategoryWeapon,
	KCategoryArmor,
	KCategoryJewelry,
	KCategoryJewelry,
	KCategoryArmor,
	KCategoryArmor,
	KCategoryArmor,
	KCategoryWeapon,
	KCategoryItem,
	KCategoryItem,
	KCategoryItem,
	KCategoryWeapon,
	KCategoryWeapon,
	KCategoryWeapon,
	KCategoryWeapon,
	KCategoryItem,
	KCategoryItem,
	KCategoryItem,
	KCategoryEvent,
	KCategoryEvent,
	KCategoryEvent,
	KCategoryEvent,
	KCategoryEvent,
	KCategoryEvent,
	KCategoryEvent,
	KCategoryEvent,
	KCategoryEvent,
};

const ESkill KSkillModifier[KItemTypes] =
{
	KSkillSword,
	KSkillSword,
	KSkillSword,
	KSkillSword,
	KSkillSword,
	KSkillSword,
	KSkillSword,
	KSkillSword,
	KSkillSword,
	KSkillSword,
	KSkillSword,
	KSkillSword,
	KSkillSword,
	KSkillSword,
	KSkillSword,
	KSkillClub,
	KSkillSword,
	KSkillSword,
	KSkillSpear,
	KSkillBow,
	KSkillSword,
	KSkillSword,
	KSkillSword,
	KSkillSword,
	KSkillSword,
	KSkillSword,
	KSkillPolearm,
	KSkillSword,
	KSkillSword,
	KSkillSword,
	KSkillAxe,
	KSkillHammer,
	KSkillStaff,
	KSkillBow,
	KSkillSword,
	KSkillSword,
	KSkillSword,
	KSkillSword,
	KSkillSword,
	KSkillSword,
	KSkillSword,
	KSkillSword,
	KSkillSword,
	KSkillSword,
	KSkillSword,
	KSkillSword
};

const std::string KWeaponAnimationRight[KItemTypes] =
{
	"NONE",
	"NONE",
	"NONE",
	"NONE",
	"NONE",
	"NONE",
	"NONE",
	"NONE",
	"NONE",
	"NONE",
	"NONE",
	"NONE",
	"NONE",
	"NONE",
	"RIGHTSLASH",
	"RIGHTSLASH",
	"NONE",
	"NONE",
	"RIGHTSTAB",
	"NONE",
	"NONE",
	"NONE",
	"NONE",
	"NONE",
	"NONE",
	"NONE",
	"RIGHTPIKESTAB",
	"NONE",
	"NONE",
	"NONE",
	"RIGHTSLASH",
	"RIGHTSLASH",
	"RIGHTPIKESTAB",
	"RIGHTCROSSBOW",
	"NONE",
	"NONE",
	"NONE",
	"NONE",
	"NONE",
	"NONE",
	"NONE",
	"NONE",
	"NONE",
	"NONE",
	"NONE",
	"NONE"
};

const std::string KWeaponAnimationLeft[KItemTypes] =
{
	"NONE",
	"NONE",
	"NONE",
	"NONE",
	"NONE",
	"NONE",
	"NONE",
	"NONE",
	"NONE",
	"NONE",
	"NONE",
	"NONE",
	"NONE",
	"NONE",
	"LEFTSLASH",
	"LEFTSLASH",
	"NONE",
	"NONE",
	"LEFTSTAB",
	"BOW",
	"NONE",
	"NONE",
	"NONE",
	"NONE",
	"NONE",
	"NONE",
	"LEFTPIKESTAB",
	"NONE",
	"NONE",
	"NONE",
	"LEFTSLASH",
	"LEFTSLASH",
	"NONE",
	"NONE",
	"NONE",
	"NONE",
	"NONE",
	"NONE",
	"NONE",
	"NONE",
	"NONE",
	"NONE",
	"NONE",
	"NONE",
	"NONE",
	"NONE"
};

enum EEffectActivation
{
	KActivationPassive,
	KActivationUsage,
	KActivationTypes
};

const std::string KActivationNames[KActivationTypes] =
{
	"PASSIVE",
	"USAGE"
};

enum ETarget
{
	KTargetUser,
	KTargetCharacter,
	KTargetArea,
	KTargetItem,
	KTargetCharacterArea,
	KTargetUserArea,
	KTargetUserPets,
	KTargetCharacterPets,
	KTargetUserAndPets,
	KTargetCharacterAndPets,
	KTargetProjectile,
	KTargets
};

static std::string GetTargetDescription( int Target )
{
	switch ( Target )
	{
	case 0: return LoadLocalizedString(349);
	case 1: return LoadLocalizedString(350);
	case 2: return LoadLocalizedString(351);
	case 3: return LoadLocalizedString(352);
	case 4: return LoadLocalizedString(353);
	case 5: return LoadLocalizedString(354);
	case 6: return LoadLocalizedString(355);
	case 7: return LoadLocalizedString(356);
	case 8: return LoadLocalizedString(357);
	case 9: return LoadLocalizedString(358);
	case 10: return LoadLocalizedString(359);
	default:
		return std::string();
	}
};

const std::string KTargetNames[KTargets] =
{
	"USER",
	"CHARACTER",
	"AREA",
	"ITEM",
	"CHARACTERAREA",
	"USERAREA",
	"USERPETS",
	"CHARACTERPETS",
	"USERANDPETS",
	"CHARACTERANDPETS",
	"PROJECTILE"
};


enum EEffectType
{
	KEffectStrength,
	KEffectDexterity,
	KEffectVitality,
	KEffectMagic,
	KEffectMaxMana,
	KEffectMaxHP,
	KEffectMaxStamina,
	KEffectMana,
	KEffectHP,
	KEffectStamina,
	KEffectArmorBonus,
	KEffectToHitBonus,
	KEffectDamageBonus,
	KEffectDamageTaken,
	KEffectKnockback,
	KEffectSkillSword,
	KEffectSkillClub,
	KEffectSkillHammer,
	KEffectSkillAxe,
	KEffectSkillSpear,
	KEffectSkillStaff,
	KEffectSkillPolearm,
	KEffectSkillBow,
	KEffectSkillCrossbow,
	KEffectSkillThrown,
	KEffectSkillDualWield,
	KEffectSkillShield,
	KEffectSkillAttackMagic,
	KEffectSkillDefenseMagic,
	KEffectSkillCharmMagic,
	KEffectPercentStrength,
	KEffectPercentDexterity,
	KEffectPercentVitality,
	KEffectPercentMagic,
	KEffectPercentMana,
	KEffectPercentHP,
	KEffectPercentStamina,
	KEffectPercentSpeed,
	KEffectPercentAttackSpeed,
	KEffectPercentArmorBonus,
	KEffectPercentToHitBonus,
	KEffectPercentDamageBonus,
	KEffectPercentDamageTaken,
	KEffectPercentMagicalDrop,
	KEffectPercentGoldDrop,
	KEffectPercentCastSpeed,
	KEffectPercentLifeStolen,
	KEffectPercentManaStolen,
	KEffectPercentDamageReflected,
	KEffectPercentBlockChance,
	KEffectPercentItemRequirements,
	KEffectPercentPiercingResistance,
	KEffectPercentSlashingResistance,
	KEffectPercentCrushingResistance,
	KEffectPercentMagicalResistance,
	KEffectPercentFireResistance,
	KEffectPercentIceResistance,
	KEffectPercentElectricResistance,
	KEffectTypes,
	KEffectRemove,
	KEffectKnockbackEffect,
	KEffectIdentify,
	KEffectWriteSpell,
	KEffectSummon,
	KEffectAddDamageType,
	KEffectTransform,
	KEffectRevertTransform,
	KEffectOpenPortal,
	KEffectDiscover,
	KEffectFlee,
	KEffectTurnAlignment,
	KEffectDispel,
	KEffectDispelEnemy,
	KAllEffectTypes
};

const EEffectType KDamageResistance[KDamageTypes] =
{
	KEffectPercentPiercingResistance,
	KEffectPercentSlashingResistance,
	KEffectPercentCrushingResistance,
	KEffectPercentMagicalResistance,
	KEffectPercentFireResistance,
	KEffectPercentIceResistance,
	KEffectPercentElectricResistance,
	KEffectPercentFireResistance
};

enum EBonusType
{
	KBonusValue,
	KBonusPercentage,
	KBonusTypes
};

enum EBonusPositive
{
	KBonusPositive,
	KBonusNegative
};

const EBonusType KEffectBonusType[KEffectTypes] =
{
	KBonusValue,
	KBonusValue,
	KBonusValue,
	KBonusValue,
	KBonusValue,
	KBonusValue,
	KBonusValue,
	KBonusValue,
	KBonusValue,
	KBonusValue,
	KBonusValue,
	KBonusValue,
	KBonusValue,
	KBonusValue,
	KBonusValue,
	KBonusValue,
	KBonusValue,
	KBonusValue,
	KBonusValue,
	KBonusValue,
	KBonusValue,
	KBonusValue,
	KBonusValue,
	KBonusValue,
	KBonusValue,
	KBonusValue,
	KBonusValue,
	KBonusValue,
	KBonusValue,
	KBonusValue,
	KBonusPercentage,
	KBonusPercentage,
	KBonusPercentage,
	KBonusPercentage,
	KBonusPercentage,
	KBonusPercentage,
	KBonusPercentage,
	KBonusPercentage,
	KBonusPercentage,
	KBonusPercentage,
	KBonusPercentage,
	KBonusPercentage,
	KBonusPercentage,
	KBonusPercentage,
	KBonusPercentage,
	KBonusPercentage,
	KBonusPercentage,
	KBonusPercentage,
	KBonusPercentage,
	KBonusPercentage,
	KBonusPercentage,
	KBonusPercentage,
	KBonusPercentage,
	KBonusPercentage,
	KBonusPercentage,
	KBonusPercentage,
	KBonusPercentage,
	KBonusPercentage
};
const bool KEffectHasValue[KAllEffectTypes] =
{
	kTrue,
	kTrue,
	kTrue,
	kTrue,
	kTrue,
	kTrue,
	kTrue,
	kTrue,
	kTrue,
	kTrue,
	kTrue,
	kTrue,
	kTrue,
	kTrue,
	kTrue,
	kTrue,
	kTrue,
	kTrue,
	kTrue,
	kTrue,
	kTrue,
	kTrue,
	kTrue,
	kTrue,
	kTrue,
	kTrue,
	kTrue,
	kTrue,
	kTrue,
	kTrue,
	kTrue,
	kTrue,
	kTrue,
	kTrue,
	kTrue,
	kTrue,
	kTrue,
	kTrue,
	kTrue,
	kTrue,
	kTrue,
	kTrue,
	kTrue,
	kTrue,
	kTrue,
	kTrue,
	kTrue,
	kTrue,
	kTrue,
	kTrue,
	kTrue,
	kTrue,
	kTrue,
	kTrue,
	kTrue,
	kTrue,
	kTrue,
	kTrue,
	kFalse,
	kFalse,
	kTrue,
	kFalse,
	kFalse,
	kFalse,
	kFalse,
	kFalse,
	kFalse,
	kFalse,
	kFalse,
	kFalse,
	kFalse
};

const bool KEffectIsRecharge[KAllEffectTypes] =
{
	kFalse,
	kFalse,
	kFalse,
	kFalse,
	kFalse,
	kFalse,
	kFalse,
	kTrue,
	kTrue,
	kTrue,
	kFalse,
	kFalse,
	kFalse,
	kFalse,
	kFalse,
	kFalse,
	kFalse,
	kFalse,
	kFalse,
	kFalse,
	kFalse,
	kFalse,
	kFalse,
	kFalse,
	kFalse,
	kFalse,
	kFalse,
	kFalse,
	kFalse,
	kFalse,
	kFalse,
	kFalse,
	kFalse,
	kFalse,
	kFalse,
	kFalse,
	kFalse,
	kFalse,
	kFalse,
	kFalse,
	kFalse,
	kFalse,
	kFalse,
	kFalse,
	kFalse,
	kFalse,
	kFalse,
	kFalse,
	kFalse,
	kFalse,
	kFalse,
	kFalse,
	kFalse,
	kFalse,
	kFalse,
	kFalse,
	kFalse,
	kFalse,
	kFalse,
	kFalse,
	kFalse,
	kFalse,
	kFalse,
	kFalse,
	kFalse,
	kFalse,
	kFalse,
	kFalse,
	kFalse,
	kFalse,
	kFalse,
	kFalse,
	kFalse
};

const std::string KEffectNames[KAllEffectTypes] =
{
	"STRENGTH",
	"DEXTERITY",
	"VITALITY",
	"MAGIC",
	"MANA",
	"HP",
	"STAMINA",
	"MANARECHARGE",
	"HPRECHARGE",
	"STAMINARECHARGE",
	"ARMORBONUS",
	"TOHITBONUS",
	"DAMAGEBONUS",
	"DAMAGETAKEN",
	"KNOCKBACK",
	"SKILLSWORD",
	"SKILLCLUB",
	"SKILLHAMMER",
	"SKILLAXE",
	"SKILLSPEAR",
	"SKILLSTAFF",
	"SKILLPOLEARM",
	"SKILLBOW",
	"SKILLCRITICALSTRIKE",
	"SKILLSPELLCASTING",
	"SKILLDUALWIELD",
	"SKILLSHIELD",
	"SKILLATTACKMAGIC",
	"SKILLDEFENSEMAGIC",
	"SKILLCHARMMAGIC",
	"PERCENTSTRENGTH",
	"PERCENTDEXTERITY",
	"PERCENTVITALITY",
	"PERCENTMAGIC",
	"PERCENTMANA",
	"PERCENTHP",
	"PERCENTSTAMINA",
	"PERCENTSPEED",
	"PERCENTATTACKSPEED",
	"PERCENTARMORBONUS",
	"PERCENTTOHITBONUS",
	"PERCENTDAMAGEBONUS",
	"PERCENTDAMAGETAKEN",
	"PERCENTMAGICALDROP",
	"PERCENTGOLDDROP",
	"PERCENTCASTSPEED",
	"PERCENTLIFESTOLEN",
	"PERCENTMANASTOLEN",
	"PERCENTDAMAGEREFLECTED",
	"PERCENTBLOCKCHANCE",
	"PERCENTITEMREQUIREMENTS",
	"PERCENTPIERCINGRESISTANCE",
	"PERCENTSLASHINGRESISTANCE",
	"PERCENTCRUSHINGRESISTANCE",
	"PERCENTMAGICALRESISTANCE",
	"PERCENTFIRERESISTANCE",
	"PERCENTICERESISTANCE",
	"PERCENTELECTRICRESISTANCE",
	"NA",
	"REMOVEEFFECT",
	"KNOCKBACKEFFECT",
	"IDENTIFY",
	"WRITESPELL",
	"SUMMON",
	"ADDDAMAGETYPE",
	"TRANSFORM",
	"REVERTTRANSFORM",
	"OPENPORTAL",
	"DISCOVER",
	"FLEE",
	"TURNALIGNMENT",
	"DISPEL",
	"DISPELENEMY"
};

// is susceptible to magic resistance?
const bool KEffectIsMagic[KAllEffectTypes] =
{
	kTrue,
	kTrue,
	kTrue,
	kTrue,
	kTrue,
	kTrue,
	kTrue,
	kTrue,
	kTrue,
	kTrue,
	kTrue,
	kTrue,
	kTrue,
	kTrue,
	kFalse,
	kFalse,
	kFalse,
	kFalse,
	kFalse,
	kFalse,
	kFalse,
	kFalse,
	kFalse,
	kFalse,
	kFalse,
	kFalse,
	kFalse,
	kFalse,
	kFalse,
	kFalse,
	kTrue,
	kTrue,
	kTrue,
	kTrue,
	kTrue,
	kTrue,
	kTrue,
	kTrue,
	kTrue,
	kTrue,
	kTrue,
	kTrue,
	kTrue,
	kFalse,
	kFalse,
	kTrue,
	kFalse,
	kFalse,
	kFalse,
	kTrue,
	kFalse,
	kFalse,
	kFalse,
	kFalse,
	kFalse,
	kFalse,
	kFalse,
	kFalse,
	kFalse,
	kFalse,
	kFalse,
	kFalse,
	kFalse,
	kFalse,
	kFalse,
	kFalse,
	kFalse,
	kFalse,
	kFalse,
	kFalse,
	kFalse,
	kFalse,
	kFalse
};

static std::string GetEffectSpellPositiveDescriptions( int EffectType )
{
	switch ( EffectType )
	{
	case 0: return LoadLocalizedString(403);
	case 1: return LoadLocalizedString(404);
	case 2: return LoadLocalizedString(405);
	case 3: return LoadLocalizedString(406);
	case 4: return LoadLocalizedString(407);
	case 5: return LoadLocalizedString(408);
	case 6: return LoadLocalizedString(409);
	case 7: return LoadLocalizedString(410);
	case 8: return LoadLocalizedString(411);
	case 9: return LoadLocalizedString(412);
	case 10: return LoadLocalizedString(413);
	case 11: return LoadLocalizedString(414);
	case 12: return LoadLocalizedString(415);
	case 13: return LoadLocalizedString(416);
	case 14: return LoadLocalizedString(417);
	case 15: return LoadLocalizedString(418);
	case 16: return LoadLocalizedString(419);
	case 17: return LoadLocalizedString(420);
	case 18: return LoadLocalizedString(421);
	case 19: return LoadLocalizedString(422);
	case 20: return LoadLocalizedString(423);
	case 21: return LoadLocalizedString(424);
	case 22: return LoadLocalizedString(425);
	case 23: return LoadLocalizedString(426);
	case 24: return LoadLocalizedString(427);
	case 25: return LoadLocalizedString(428);
	case 26: return LoadLocalizedString(429);
	case 27: return LoadLocalizedString(430);
	case 28: return LoadLocalizedString(431);
	case 29: return LoadLocalizedString(432);
	case 30: return LoadLocalizedString(433);
	case 31: return LoadLocalizedString(434);
	case 32: return LoadLocalizedString(435);
	case 33: return LoadLocalizedString(436);
	case 34: return LoadLocalizedString(437);
	case 35: return LoadLocalizedString(438);
	case 36: return LoadLocalizedString(439);
	case 37: return LoadLocalizedString(440);
	case 38: return LoadLocalizedString(441);
	case 39: return LoadLocalizedString(442);
	case 40: return LoadLocalizedString(443);
	case 41: return LoadLocalizedString(444);
	case 42: return LoadLocalizedString(445);
	case 43: return LoadLocalizedString(446);
	case 44: return LoadLocalizedString(447);
	case 45: return LoadLocalizedString(448);
	case 46: return LoadLocalizedString(449);
	case 47: return LoadLocalizedString(450);
	case 48: return LoadLocalizedString(451);
	case 49: return LoadLocalizedString(452);
	case 50: return LoadLocalizedString(453);
	case 51: return LoadLocalizedString(454);
	case 52: return LoadLocalizedString(455);
	case 53: return LoadLocalizedString(456);
	case 54: return LoadLocalizedString(457);
	case 55: return LoadLocalizedString(458);
	case 56: return LoadLocalizedString(459);
	case 57: return LoadLocalizedString(460);
	case 58: return LoadLocalizedString(461);
	case 59: return LoadLocalizedString(462);
	case 60: return LoadLocalizedString(463);
	case 61: return LoadLocalizedString(464);
	case 62: return LoadLocalizedString(465);
	case 63: return LoadLocalizedString(466);
	case 64: return LoadLocalizedString(467);
	case 65: return LoadLocalizedString(468);
	case 66: return LoadLocalizedString(469);
	case 67: return LoadLocalizedString(470);
	case 68: return LoadLocalizedString(471);
	case 69: return LoadLocalizedString(472);
	case 70: return LoadLocalizedString(473);
	case 71: return LoadLocalizedString(474);
	case 72: return LoadLocalizedString(547);
	default:
		return std::string();
	}
};

static std::string GetEffectItemNegativeDescriptions(int EffectType )
{
	switch ( EffectType )
	{
	case 0: return LoadLocalizedString(475);
	case 1: return LoadLocalizedString(476);
	case 2: return LoadLocalizedString(477);
	case 3: return LoadLocalizedString(478);
	case 4: return LoadLocalizedString(479);
	case 5: return LoadLocalizedString(480);
	case 6: return LoadLocalizedString(481);
	case 7: return LoadLocalizedString(482);
	case 8: return LoadLocalizedString(483);
	case 9: return LoadLocalizedString(484);
	case 10: return LoadLocalizedString(485);
	case 11: return LoadLocalizedString(486);
	case 12: return LoadLocalizedString(487);
	case 13: return LoadLocalizedString(488);
	case 14: return LoadLocalizedString(489);
	case 15: return LoadLocalizedString(490);
	case 16: return LoadLocalizedString(491);
	case 17: return LoadLocalizedString(492);
	case 18: return LoadLocalizedString(493);
	case 19: return LoadLocalizedString(494);
	case 20: return LoadLocalizedString(495);
	case 21: return LoadLocalizedString(496);
	case 22: return LoadLocalizedString(497);
	case 23: return LoadLocalizedString(498);
	case 24: return LoadLocalizedString(499);
	case 25: return LoadLocalizedString(500);
	case 26: return LoadLocalizedString(501);
	case 27: return LoadLocalizedString(502);
	case 28: return LoadLocalizedString(503);
	case 29: return LoadLocalizedString(504);
	case 30: return LoadLocalizedString(505);
	case 31: return LoadLocalizedString(506);
	case 32: return LoadLocalizedString(507);
	case 33: return LoadLocalizedString(508);
	case 34: return LoadLocalizedString(509);
	case 35: return LoadLocalizedString(510);
	case 36: return LoadLocalizedString(511);
	case 37: return LoadLocalizedString(512);
	case 38: return LoadLocalizedString(513);
	case 39: return LoadLocalizedString(514);
	case 40: return LoadLocalizedString(515);
	case 41: return LoadLocalizedString(516);
	case 42: return LoadLocalizedString(517);
	case 43: return LoadLocalizedString(518);
	case 44: return LoadLocalizedString(519);
	case 45: return LoadLocalizedString(520);
	case 46: return LoadLocalizedString(521);
	case 47: return LoadLocalizedString(522);
	case 48: return LoadLocalizedString(523);
	case 49: return LoadLocalizedString(524);
	case 50: return LoadLocalizedString(525);
	case 51: return LoadLocalizedString(526);
	case 52: return LoadLocalizedString(527);
	case 53: return LoadLocalizedString(528);
	case 54: return LoadLocalizedString(529);
	case 55: return LoadLocalizedString(530);
	case 56: return LoadLocalizedString(531);
	case 57: return LoadLocalizedString(532);
	case 58: return LoadLocalizedString(533);
	case 59: return LoadLocalizedString(534);
	case 60: return LoadLocalizedString(535);
	case 61: return LoadLocalizedString(536);
	case 62: return LoadLocalizedString(537);
	case 63: return LoadLocalizedString(538);
	case 64: return LoadLocalizedString(539);
	case 65: return LoadLocalizedString(540);
	case 66: return LoadLocalizedString(541);
	case 67: return LoadLocalizedString(542);
	case 68: return LoadLocalizedString(543);
	case 69: return LoadLocalizedString(544);
	case 70: return LoadLocalizedString(545);
	case 71: return LoadLocalizedString(546);
	case 72: return LoadLocalizedString(547);
	default:
		return std::string();
	}
};

static std::string GetEffectItemPositiveDescriptions( int EffectType )
{
	if (( EffectType < 0) || ( EffectType >= KEffectTypes ) )
		return std::string();

	return LoadLocalizedString( 403 + EffectType);
};

static std::string GetEffectSpellNegativeDescriptions( int EffectType )
{
	if (( EffectType < 0) || ( EffectType >= KEffectTypes ) )
		return std::string();

	return LoadLocalizedString( 475 + EffectType);
};

const uint32 KPositiveSuffixes( 5 );
constexpr int KPositivePrefixSuffix[KEffectTypes][KPositiveSuffixes] =
{
	{ 548,549,550,551,552 },
	{ 553,554,555,556,557 },
	{ 558,559,560,561,562 },
	{ 563,564,565,566,567 },
	{ 568,569,570,571,572 }, 
	{ 573,574,575,576,577 },
	{ 578,579,580,581,582 },
	{ 583,584,585,586,587 },
	{ 588,589,590,591,592 },
	{ 593,594,595,596,597 },
	{ 598,599,600,601,602 },
	{ 603,604,605,606,607 },
	{ 608,609,610,611,612 },
	{ 613,614,615,616,617 },
	{ 618,619,620,621,622 },
	{ 623,624,625,626,627 },
	{ 623,624,625,626,627 },
	{ 623,624,625,626,627 },
	{ 623,624,625,626,627 },
	{ 623,624,625,626,627 },
	{ 623,624,625,626,627 },
	{ 623,624,625,626,627 },
	{ 623,624,625,626,627 },
	{ 623,624,625,626,627 },
	{ 623,624,625,626,627 },
	{ 623,624,625,626,627 },
	{ 623,624,625,626,627 },
	{ 623,624,625,626,627 },
	{ 623,624,625,626,627 },
	{ 623,624,625,626,627 },
	{ 628,629,630,631,632 },
	{ 633,634,635,636,637 },
	{ 638,639,640,641,642 },
	{ 643,644,645,646,647 },
	{ 648,649,650,651,652 },
	{ 653,654,655,656,657 },
	{ 658,659,660,661,662 },
	{ 663,664,665,666,667 },
	{ 668,669,670,671,672 },
	{ 673,674,675,676,677 },
	{ 678,679,680,681,682 },
	{ 683,684,685,686,687 },
	{ 688,689,690,691,692 },
	{ 693,694,695,696,697 },
	{ 698,699,700,701,702 },
	{ 703,704,705,706,707 },
	{ 708,709,710,711,712 },
	{ 713,714,715,716,717 },
	{ 718,719,720,721,722 },
	{ 723,724,725,726,727 },
	{ 728,729,730,731,732 },
	{ 733,733,733,733,733 },
	{ 733,733,733,733,733 },
	{ 733,733,733,733,733 },
	{ 733,733,733,733,733 },
	{ 733,733,733,733,733 },
	{ 733,733,733,733,733 },
	{ 733,733,733,733,733 }

};

static std::string GetPositivePrefixSuffix(int EffectType, int PositiveSuffix )
{
	if (( EffectType < 0) || ( EffectType >= KEffectTypes ) )
		return std::string();
	if (( PositiveSuffix < 0) || ( PositiveSuffix >= KPositiveSuffixes ) )
		return std::string();

	return LoadLocalizedString( KPositivePrefixSuffix[EffectType][PositiveSuffix] );
};


const uint32 KNegativeSuffixes( 2 );
constexpr int KNegativePrefixSuffix[KEffectTypes][KNegativeSuffixes] =
{
	{ 734, 735 },
	{ 736, 737 },
	{ 738, 739 },
	{ 740, 741 },
	{ 742, 743 },
	{ 744, 745 },
	{ 746, 747 },
	{ 748, 749 },
	{ 750, 751 },
	{ 752, 753 },
	{ 754, 755 },
	{ 756, 757 },
	{ 758, 759 },
	{ 760, 761 },
	{ -1, -1 },
	{ -1, -1 },
	{ -1, -1 },
	{ -1, -1 },
	{ -1, -1 },
	{ -1, -1 },
	{ -1, -1 },
	{ -1, -1 },
	{ -1, -1 },
	{ -1, -1 },
	{ -1, -1 },
	{ -1, -1 },
	{ -1, -1 },
	{ -1, -1 },
	{ -1, -1 },
	{ -1, -1 },
	{ 762, 763 },
	{ 764, 765 },
	{ 766, 767 },
	{ 768, 769 },
	{ 770, 771 },
	{ 772, 773 },
	{ 774, 775 },
	{ 776, 777 },
	{ 778, 779 },
	{ 780, 781 },
	{ 782, 783 },
	{ 784, 785 },
	{ 786, 787 },
	{ 788, 789 },
	{ 790, 791 },
	{ 792, 793 },
	{ 794, 795 },
	{ 796, 797 },
	{ 798, 799 },
	{ 800, 801 },
	{ 802, 803 },
	{ 804, 804 },
	{ 804, 804 },
	{ 804, 804 },
	{ 804, 804 },
	{ 804, 804 },
	{ 804, 804 },
	{ 804, 804 }
};

static std::string GetNegativePrefixSuffix( int EffectType, int NegativeSuffix )
{
	if (( EffectType < 0) || ( EffectType >= KEffectTypes ) )
		return std::string();
	if (( NegativeSuffix < 0) || ( NegativeSuffix >= KNegativeSuffixes ) )
		return std::string();

	int rcIndex = KNegativePrefixSuffix[EffectType][NegativeSuffix];
	return rcIndex > -1 ? LoadLocalizedString(rcIndex) : std::string();
}

const int32 KEffectMinimum[KEffectTypes] =
{
	-10,
	-10,
	-10,
	-10,
	-10,
	-10,
	-5,
	-5,
	-5,
	-10,
	-10,
	-10,
	-10,
	30,
	0,
	0,
	0,
	0,
	0,
	0,
	0,
	0,
	0,
	0,
	0,
	0,
	0,
	0,
	0,
	0,
	-50,
	-50,
	-50,
	-50,
	-50,
	-50,
	-50,
	-20,
	-20,
	-50,
	-50,
	-50,
	30,
	0,
	0,
	0,
	-30,
	-30,
	0,
	-30,
	-30,
	-30,
	-30,
	-30,
	-30,
	-30,
	-30,
	-30
};

const int32 KEffectMaximum[KEffectTypes] =
{
	30,
	30,
	30,
	30,
	30,
	30,
	10,
	10,
	10,
	30,
	30,
	30,
	30,
	-10,
	10,
	20,
	20,
	20,
	20,
	20,
	20,
	20,
	20,
	20,
	20,
	20,
	20,
	20,
	20,
	20,
	50,
	50,
	50,
	50,
	50,
	50,
	50,
	30,
	30,
	50,
	50,
	50,
	-30,
	30,
	100,
	20,
	8,	// life stolen
	10,
	10,
	10, 
	10,
	30,
	30,
	30,
	30,
	30,
	30,
	30
};

const int32		 KUnlimitedUses( -9999 );
const int32		 KDurationInstant( -900 );
const int32		 KDurationAlways( -1000 );

enum EEffectTarget
{
	KEffectUser,
	KEffectTarget,
	KEffectTargets
};

enum ELightPoolType
{
	KLightFlicker,
	KLightPulse
};

const uint32 KExperienceGates = 100;
const uint32 KExperienceGate[KExperienceGates] =
{
	0,
	847,
	1424,
	2379,
	3946,
	6498,
	10623,
	17241,
	27779,
	44432,
	70546,
	111183,
	173930,
	251775,
	263013,
	294761,
	337798,
	380835,
	423872,
	466909,
	509946,
	552984,
	596021,
	659538,
	725587,
	791636,
	857685,
	923734,
	989782,
	1055831,
	1121880,
	1208774,
	1300717,
	1392659,
	1484602,
	1576545,
	1668488,
	1760431,
	1871890,
	1999642,
	2127395,
	2255147,
	2382899,
	2510652,
	2638404,
	2766156,
	2893909,
	3027737,
	3198893,
	3370048,
	3541204,
	3712359,
	3883514,
	4054670,
	4225825,
	4396980,
	4602433,
	4834834,
	5067234,
	5299635,
	5532035,
	5764436,
	5996836,
	6229237,
	6487487,
	6752000,
	7016513,
	7281026,
	7545538,
	7810051,
	8074564,
	8339077,
	8637166,
	9050909,
	9464652,
	9878396,
	10292139,
	10705882,
	11119625,
	11533368,
	11972685,
	12412931,
	12853176,
	13293421,
	13733666,
	14210761,
	14754810,
	15298858,
	15842906,
	16386955,
	16966785,
	17573608,
	18180431,
	18787255,
	19462627,
	20181825,
	20901024,
	21693940,
	22528322,
	24137891

};

// base AC for all characters
const int32 KBaseArmorClass( 10 );

inline int32 AbilityModifier( int32 Ability )
{
	Ability -= 10;

	int32 Modifier = (int32)floor( (float32)Ability / 2 );
	return Modifier;
}

inline int32 RollDie( int32 Sides ) 
{
	return 1 + rand() % Sides;
}


inline int32 RollDice( int32 Dice, int32 Sides ) 
{
	int32 Sum( Dice );
	for ( int32 i = 0; i < Dice; i++ )
	{
		Sum += rand() % Sides;
	}
	return Sum;
}

inline int32 MinDiceRoll( int32 Dice, int32 Sides )
{
	return Dice;
}

inline int32 MaxDiceRoll( int32 Dice, int32 Sides )
{
	return Dice * Sides;
}

inline int32 ExperienceGate( int32 Level )
{
	if( Level == 0 )
	{
		return 0;
	}
	if( Level > 99 )
	{
		Level = 99;
	}
	return KExperienceGate[Level];
}

class CSFXDescription
{
public:
	CSFXDescription( ESFXType SFXType,						// type of sfx this is
					 const std::string& Path,				// path to animated mesh
					 float32 Duration,						// lifetime ( -1 to end when animation ends )
					 bool Looping,							// loop the animation? nonapplicable for a time of -1
					 float32 Speed,							// projectile speed
					 float32 TurnRate,
					 bool Exclusive,						// projectile turn rate
					 bool RespectBonuses ) :				// respect duration bonuses
					 m_Duration( Duration ),
					 m_Looping( Looping ),
					 m_Exclusive( Exclusive ),
					 m_Path( Path ),
					 m_Type( SFXType ),
					 m_Speed( Speed ),
					 m_TurnRate( TurnRate ),
					 m_RespectBonuses( RespectBonuses )
	{
	}
	CSFXDescription( CSFXDescription* pDescription ) :	// description to copy
					 m_Duration( pDescription->m_Duration ),
					 m_Looping( pDescription->m_Looping ),
					 m_Exclusive( pDescription->m_Exclusive ),
					 m_Path( pDescription->m_Path ),
					 m_Type( pDescription->m_Type ),
					 m_Speed( pDescription->m_Speed ),
					 m_TurnRate( pDescription->m_TurnRate ),
					 m_RespectBonuses( pDescription->m_RespectBonuses )
	{
	}

	ESFXType	m_Type;
	std::string	m_Path;
	float32		m_Duration;
	bool		m_Looping;
	bool		m_Exclusive;
	bool		m_RespectBonuses;
	float32		m_Speed;
	float32		m_TurnRate;
};

#endif

